package com.joven.shelltest.service.impl;

import com.joven.shelltest.model.ConutFlux;
import com.joven.shelltest.service.ShellService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.*;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

/**
 * @author joven_wong
 * 2022/9/15 16:37
 */
@Slf4j
@Service("shellService")
public class ShellServiceImpl  implements ShellService {
    private final static String FLUX_REGEX = "#";

    @Override
    public void createShell(String path, String... strs) throws Exception {
        if (strs == null) {
            System.out.println("strs is null");
            return;
        }
        File sh = new File(path);
        if (sh.exists()) {
            sh.delete();
        }
        sh.createNewFile();
        sh.setExecutable(true);
        FileWriter fw = new FileWriter(sh);
        BufferedWriter bf = new BufferedWriter(fw);
        for (int i = 0; i < strs.length; i++) {
            bf.write(strs[i]);
            if (i < strs.length - 1) {
                bf.newLine();
            }
        }
        bf.flush();
        bf.close();
    }

    @Override
    public String runShell(String shpath) throws Exception {
        if (shpath == null || "".equals(shpath)) {
            return "shpath is empty";
        }
        Process ps = Runtime.getRuntime().exec(shpath);
        ps.waitFor();
        BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line).append("\n");
        }
        String reuslt = sb.toString();
        log.info("执行输出结果：{}",reuslt);
        return reuslt;

    }

    @Override
    public void callShell(String path, String args, String... workspace) throws IOException, InterruptedException {
        //String cmd = "sh " + path + " " + args;
        String cmd = "cat " + path + " " + args;
//        File dir = null;
//        if(workspace[0] != null){
//            dir = new File(workspace[0]);
//            System.out.println(workspace[0]);
//        }
//        String[] evnp = {"val=2", "call=Bash Shell"};
//        evnp 可以为空
        //Process process = Runtime.getRuntime().exec(cmd, null, dir);
        //Process process = Runtime.getRuntime().exec(cmd, evnp, dir);
        Process process = Runtime.getRuntime().exec(cmd, null);
        BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = "";
        while ((line = input.readLine()) != null) {
            System.out.println("当前行:"+line);
            String[] result = line.split(FLUX_REGEX);
            System.out.println(Arrays.toString(result));
            ConutFlux flux = new ConutFlux();
            flux.setRemark(result[2]);
            flux.setEntrance(result[3]);
            flux.setSpeak(result[4]);
            flux.setFluxNum(result[result.length - 1]);
            System.out.println(flux.toString());
        }
        input.close();
    }

    @Override
    public void executeCountFlux(String[] path) {
        Map<String, Integer> countMap = new ConcurrentHashMap<>();
        CountDownLatch endLatch = new CountDownLatch(5);
        String args = "";
        Runnable runnable3 = () -> {
            threadProcessCount("/opt/xasz/logs/app/xa-qtm-query/" + path[0] + ".log", args, countMap);
            endLatch.countDown();
        };
        Runnable runnable4 = () -> {
            threadProcessCount("/opt/xasz/logs/app/xa-qtm-query/" + path[1] + ".log", args, countMap);
            endLatch.countDown();
        };
        Runnable runnable5 = () -> {
            threadProcessCount("/opt/xasz/logs/app/xa-qtm-query/" + path[2] + ".log", args, countMap);
            endLatch.countDown();
        };
        Runnable runnable9 = () -> {
            threadProcessCount("/opt/xasz/logs/app/xa-qtm-query/" + path[3] + ".log", args, countMap);
            endLatch.countDown();
        };
        Runnable runnable10 = () -> {
            threadProcessCount("/opt/xasz/logs/app/xa-qtm-query/" + path[4] + ".log", args, countMap);
            endLatch.countDown();
        };
        new Thread(runnable3).start();
        new Thread(runnable4).start();
        new Thread(runnable5).start();
        new Thread(runnable9).start();
        new Thread(runnable10).start();
        try {
            //此方法用来当前线程阻塞，直到count减少为0才恢复执行，await方法它会去获取同步值发现为0的话会返回成功，如果小于0的话，再次判断是否是头结点
            endLatch.await();
            for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
                String[] fluxKey = entry.getKey().split(FLUX_REGEX);
                Integer fluxNum = entry.getValue();
                //fluxKey[0] 备注  fluxKey[1] 入口  fluxKey[2] 出口
                log.info("key:" + Arrays.toString(fluxKey) + ",当前值：" + fluxNum);

            }
        } catch (InterruptedException e) {
            log.error("系统异常：{}", e.getMessage());
        }
    }

    private void threadProcessCount(String path, String args, Map<String, Integer> countMap) {
        log.info("开始读取path：{}", path);
        String cmd = "cat " + path + " " + args;
        Process process;
        try {
            process = Runtime.getRuntime().exec(cmd, null);
            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = input.readLine()) != null) {
                String[] result = line.split(FLUX_REGEX);
                //result[2] 备注  result[3] 入口  result[4] 出口
                String mapKey = result[2] + "#" + result[3] + "#" + result[4];
                String fluxNum = result[result.length - 1];
                log.info("mapKey:{},fluxNum:{}", mapKey, fluxNum);
                if (countMap.containsKey(mapKey)) {
                    int old = countMap.get(mapKey);
                    int now = Integer.parseInt(fluxNum);
                    countMap.put(mapKey, old + now);
                    log.info("mapKey:{},fluxNumNow:{}", mapKey, (old + now));
                } else {
                    countMap.put(mapKey, Integer.parseInt(fluxNum));
                }
            }
            input.close();
        } catch (IOException e) {
            log.error("读取文件失败：{}", e.getMessage());
        }
    }
}
